#include <BleKeyboard.h>

#define BUTTON_PIN 0  // ESP32的BOOT按钮通常连接到GPIO0

BleKeyboard bleKeyboard("ESP32 Player"); // 创建蓝牙键盘设备

// 定义音阶映射
const char* str_scale1 = "asdfghj"; // 低八度
const char* str_scale2 = "qwertyu"; // 中八度
const char* str_scale3 = "zxcvbnm"; // 高八度

const float bpm = 58.0;
const float speed = 60.0 / bpm;  // 计算每拍的时间（秒）

// 合并所有音符序列
const char* all_items[] = {
  // str_array1
  "#|6|0.5", "+|3|0.25", "#|7|0.25", "#|7|1",
  // str_array2
  "#|7|0.5", "#|5|0.25", "#|6|0.25", "#|6|1",
  // str_array3
  "+|1|0.5", "#|7|0.5", "#|7|0.25", "#|6|0.5", "#|5|0.25",
  // str_array4
  "#|5|0.25", "#|6|0.5", "#|2|0.25", "#|3|1",
  // str_array5
  "#|6|0.25", "#|7|0.5", "+|1|0.25", "+|1|0.75", "#|6|0.5",
  // str_array6
  "+|3|0.5", "+|2|0.25", "#|6|0.25", "#|6|1",
  // str_array7
  "+|1|0.5", "#|7|0.25", "#|5|0.25", "#|5|0.25", "#|3|0.25", "#|7|0.5", "#|6|1.5",
  // str_array8 孤单魂
  "+|1|0.75", "+|2|0.25", "+|3|1", "#|6|0.25", "+|3|0.25", "#|5|0.25", "#|5|0.75", "#|0|0.5",
  // str_array9
  "#|6|0.25", "#|7|0.25", "+|1|0.5", "#|7|0.25", "#|7|0.25", "#|6|0.25", "#|5|0.5", "#|2|0.25", "#|3|1.5", "#|0|0.5",
  // str_array10
  "+|1|0.25", "+|2|0.25", "+|3|0.25", "+|2|0.25", "+|3|0.25", "+|2|0.25", "+|3|0.5", "+|6|0.25", "+|6|0.25", "+|3|0.25", "+|2|0.25", "+|2|1.5",
  // str_array11
  "+|1|0.25", "#|7|0.25", "#|6|0.25", "#|5|0.25", "#|5|0.25", "#|3|0.25", "#|3|0.25", "#|7|0.25", "#|6|0.5", "#|6|1.5",
  // str_array12
  "+|6|1", "+|6|0.25", "+|3|0.5", "+|6|0.25", "+|5|0.25", "+|5|0.75", "+|5|1",
  // str_array13
  "+|2|0.25", "+|1|0.25", "+|2|0.25", "+|1|0.25", "#|6|0.25", "#|5|0.25", "+|5|0.5", "+|6|0.25", "+|3|0.25", "+|3|1",
  // str_array14 望明月心悲凉
  "+|6|1", "+|6|0.25", "+|3|0.5", "+|6|0.25", "+|5|0.25", "+|5|0.5", "+|6|0.25", "+|3|0.25", "+|2|0.25", "+|2|0.25", "+|1|0.25", "#|0|0.75", "#|6|0.25", "#|6|0.25", "#|5|0.25", "#|6|0.25", "+|3|0.25", "+|3|0.75", "+|3|1",
  // str_array15 过情关
  "+|6|1", "+|6|0.25", "+|3|0.5", "+|6|0.25", "+|5|0.25", "+|5|0.75", "+|5|1",
  // str_array16
  "+|2|0.25", "+|1|0.25", "+|2|0.5", "+|1|0.25", "#|6|0.25", "#|5|0.5", "+|5|0.25", "+|6|0.25", "+|3|0.25", "+|3|1.5",
  // str_array17 眼一闭,没有高两个八度的1(do),只能用高音区的1(do)
  "+|6|1", "+|6|0.25", "+|1|0.5", "+|7|0.25", "+|7|0.5", "+|6|0.25", "+|5|0.25", "+|5|0.75", "+|6|0.25", "#|0|0.5", "+|1|0.25", "#|6|0.25", "#|5|0.25", "#|6|0.5", "+|1|0.5", "+|1|0.25", "+|2|0.25", "+|1|1", "#|0|1",
  // str_array18
  "+|1|0.25", "+|2|0.25", "+|3|1", "+|3|0.25", "+|3|0.25", "+|3|0.5", "+|5|0.25", "#|5|0.25", "#|6|0.25", "#|5|0.25", "#|5|1",
  // str_array19
  "+|1|0.25", "#|7|0.25", "#|6|0.25", "#|5|0.25", "#|5|0.25", "#|3|0.25", "#|3|0.5", "#|7|0.25", "#|6|0.25", "#|6|1.5",
  // 重复部分
  "+|1|0.25", "+|2|0.25", "+|3|1", "+|3|0.25", "+|3|0.25", "+|3|0.5", "+|5|0.25", "#|5|0.25", "#|6|0.25", "#|5|0.25", "#|5|1",
  "+|1|0.25", "#|7|0.25", "#|6|0.25", "#|5|0.25", "#|5|0.25", "#|3|0.25", "#|3|0.5", "#|7|0.25", "#|6|0.25", "#|6|1.5"
};

const int totalNotes = sizeof(all_items) / sizeof(all_items[0]);

// 状态变量
bool isPlaying = false;
bool buttonPressed = false;
int currentNote = 0;

void setup() {
  Serial.begin(115200);
  pinMode(BUTTON_PIN, INPUT_PULLUP); // BOOT按钮设置为上拉输入
  bleKeyboard.begin();  // 初始化蓝牙键盘
  
  Serial.println("等待蓝牙连接...");
  while (!bleKeyboard.isConnected()) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("\n已连接! 按BOOT按钮开始播放");
}

void loop() {
  // 检查按钮状态
  checkButton();
  
  // 如果正在播放且蓝牙已连接
  if (isPlaying && bleKeyboard.isConnected()) {
    if (currentNote < totalNotes) {
      playNote(all_items[currentNote]);
      currentNote++;
    } else {
      // 播放完成
      Serial.println("播放完成!");
      isPlaying = false;
      currentNote = 0;
    }
  }
  
  delay(10); // 防止CPU过载
}

void checkButton() {
  // 读取按钮状态（按下时为LOW）
  int buttonState = digitalRead(BUTTON_PIN);
  
  // 检测按钮按下（防抖处理）
  if (buttonState == LOW) {
    if (!buttonPressed) {
      buttonPressed = true;
      delay(50); // 防抖延迟
      
      // 确认按钮仍然按下
      if (digitalRead(BUTTON_PIN) == LOW) {
        // 切换播放状态
        isPlaying = !isPlaying;
        
        if (isPlaying) {
          Serial.println("开始播放...");
          currentNote = 0; // 从第一音符开始
        } else {
          Serial.println("停止播放");
          currentNote = 0; // 重置播放位置
        }
      }
    }
  } else {
    buttonPressed = false;
  }
}

void playNote(const char* item) {
  // 解析字符串
  char type;
  int note;
  float duration;
  sscanf(item, "%c|%d|%f", &type, &note, &duration);
  
  char key = 0;
  if (type == '#') {
    if (note != 0) key = str_scale1[note - 1];
  } else if (type == '+') {
    key = str_scale2[note - 1];
  } else if (type == '-') {
    key = str_scale3[note - 1];
  }
  
  unsigned long interval = speed * duration * 1000;  // 转换为毫秒
  
  // 打印调试信息
  Serial.print("播放: ");
  Serial.print(item);
  if (key != 0) {
    Serial.print(" -> 按键: ");
    Serial.print(key);
  }
  Serial.print(" 时长: ");
  Serial.print(interval);
  Serial.println("ms");
  
  if (key == 0) {  // 休止符
    delay(interval);
  } else {
    if (interval >= speed * 0.75 * 1000) {
      bleKeyboard.press(key);
      delay(interval);
      bleKeyboard.release(key);
      delay(100);  // 添加释放延迟
    } else {
      bleKeyboard.press(key);
      delay(30);   // 短按持续时间
      bleKeyboard.release(key);
      delay(interval > 30 ? interval - 30 : 0);
    }
  }
}